﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using NLog;
using WebApiCoreDemo.Api.Filters;
using WebApiCoreDemo.Common;

namespace WebApiCoreDemo.Api
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            //配置NLog(2)，第一步在Program.cs中
            NLog.Web.NLogBuilder.ConfigureNLog("nlog.config");
            LogManager.Configuration.Variables["connectionString"] = Configuration["SqlServerConnection:Value"];
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //自定义MyHttpContext(1)
            services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            services.AddSingleton<CustomActionFilterAttribute>();
            
            //配置跨域(1)
            services.AddCors(options => options.AddPolicy("AllowCors", (builder) =>
            {
                builder.WithOrigins(new string[] { "http://127.0.0.1:5500" }).AllowAnyHeader().AllowAnyMethod();
            }));

            //配置Swagger(1)
            services.AddSwaggerGen(m => 
            {
                m.SwaggerDoc("v1", new OpenApiInfo
                {
                    Title = "WebApiCoreDemo",
                    Version = "v1"
                });
            });

            services.AddControllers();

            #region 全局注册过滤器
            //执行顺序：全局OnActionExecuting()->控制器OnActionExecuting()->方法OnActionExecuting()->方法OnActionExecuted()->控制器OnActionExecuted()->全局OnActionExecuted()
            services.AddMvc(options =>
            {
                options.Filters.Add(typeof(CustomActionFilterAttribute));
            });
            #endregion

            #region 注册JWT鉴权授权服务
            var validAudience = this.Configuration["Audience"];
            var validIssuer = this.Configuration["Issuer"];
            var securityKey = this.Configuration["SecurityKey"];
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,//是否验证Issuer
                        ValidateAudience = true,//是否验证Audience
                        ValidateLifetime = true,//是否验证失效时间
                        ValidateIssuerSigningKey = true,//是否验证SecurityKey
                        ValidIssuer = validIssuer,//此值跟授权中心签发token所用值相同
                        ValidAudience = validAudience,//此值跟授权中心签发token所用值相同
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey)),
                        //AudienceValidator = (m, n, z) => 
                        //{
                        //    return m != null && m.FirstOrDefault().Equals(this.Configuration["Audience"]);
                        //}//自定义校验规则，新登陆后将之前的置为无效
                    };
                });
            #endregion
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            //配置鉴权授权中间件
            app.UseAuthentication();

            app.UseAuthorization();

            //配置跨域(2)
            app.UseCors("AllowCors");

            //配置Swagger(2)，在launchSettings.json修改起始页
            app.UseSwagger();
            app.UseSwaggerUI(m =>
            {
                //此处的v1要跟SwaggerDoc()的第一个参数值一致
                m.SwaggerEndpoint("/swagger/v1/swagger.json", "swaggerTest");
            });

            //自定义MyHttpContext（2）
            app.UseStaticHttpContext();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}
